﻿
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Markup;
using System.Windows.Threading;
using ZDK.Infra.Constants;
using ZDK.Infra.Events;
using ZDK.Infra.Models;
using ZDK.Infra.Services;
using ZDK.Infra.Types;
using ZDK.Utilities;

namespace ZDK.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        readonly Dispatcher _dispatcher = Dispatcher.CurrentDispatcher;

        readonly IMyLog _log;
        readonly IDialogService _dlgSvc;
        readonly ICfgService _cfgSvc;
        readonly IEventAggregator _evtAggr;
        //已连接客户端
        private ObservableCollection<string> _clientKeyList = new ObservableCollection<string>();
        public ObservableCollection<string> ClientKeyList { get => _clientKeyList; set => SetProperty(ref _clientKeyList, value); }
        private string selClientKey;
        public string SelClientKey { get => selClientKey; set => SetProperty(ref selClientKey, value); }

        public static TcpServer TCPServer { get; set; }

        #region 绑定属性
        private string listenBtnText = "开始监听";
        public string ListenBtnText { get => listenBtnText; set => SetProperty(ref listenBtnText, value); }
        private string title = "综合设备箱调试工具";
        public string Title { get => title; set => SetProperty(ref title, value); }

        #endregion

        #region 命令

        #region 打开设置窗口
        private DelegateCommand openSettingsCmd;
        public DelegateCommand OpenSettingsCmd => openSettingsCmd ?? (openSettingsCmd = new DelegateCommand(OpenSettings));
        void OpenSettings() 
        {
            _dlgSvc.ShowDialog("Settings", cb => { 
                if(cb.Result == ButtonResult.Yes) {
                    
                }
            });
        }
        #endregion

        #region 开始监听
        private DelegateCommand toggleListenCmd;
        public DelegateCommand ToggleListenCmd => toggleListenCmd ?? (toggleListenCmd = new DelegateCommand(ToggleListen));
        void ToggleListen() 
        {
            var cfg = _cfgSvc.Get();
            ListenBtnText = "停止监听";
            Title += $"({cfg.app.version})";
            if (TCPServer == null)
            {
                TCPServer = new TcpServer(_log, cfg.net.listenPort, 100);
                TCPServer.OnConnect += new DelegateMsgWithParam(OnConnect);
                TCPServer.OnReceive += new DelegateMsgWithParam(OnReceive);
                TCPServer.OnServerDown += new DelegateMsg((key) =>
                {
                    _evtAggr.GetEvent<OnDisConnEvent>().Publish((string)key);
                    _dispatcher.Invoke(new Action(() =>
                    {
                        _clientKeyList.Remove((string)key);
                    }));
                });
                TCPServer.StartServer();
            }
            else
            {
                TCPServer.Close();
                TCPServer = null;
                ListenBtnText = "开始监听";
                _log.Warn("服务端已停止监听...");
            }
        }
        #endregion

        #region 切换客户端
        private DelegateCommand clientKeySelChangedCmd;
        public DelegateCommand ClientKeySelChangedCmd => clientKeySelChangedCmd ?? (clientKeySelChangedCmd = new DelegateCommand(ClientKeySelChanged));
        void ClientKeySelChanged() 
        {
            //让FuncView知道选择的哪个client
            _evtAggr.GetEvent<ClientKeySelChangedEvent>().Publish(selClientKey);
        }

        #endregion

        #region 打印测试日志
        private DelegateCommand testLogCmd;
        public DelegateCommand TestLogCmd => testLogCmd ?? (testLogCmd = new DelegateCommand(TestLog));
        void TestLog()
        {
            _log.Info("测试日志");
        }
        #endregion

        #endregion

        public MainWindowViewModel(IMyLog mylog, IDialogService dlgSvc, ICfgService cfgSvc, IEventAggregator evtAggr)
        {
            _log = mylog;
            _dlgSvc = dlgSvc;
            _cfgSvc = cfgSvc;
            _evtAggr = evtAggr;
        }

        #region TCP

        #region OnConnect 连接
        void OnConnect(string key, object o)
        {
            _log.Info($"客户端:{key} 已连接");

            _dispatcher.Invoke(new Action(() =>
            {
                ClientKeyList.Add(key);
            }));
            SelClientKey = key;

            _evtAggr.GetEvent<OnConnEvent>().Publish(key);
        }
        #endregion

        #region OnReceive 解析报文
        void OnReceive(string key, object msg)
        {
            byte[] data = msg as byte[];
            if (data.Length < (int)FramePosEnum.FramePostEnd) return;

            _log.Info($"[{key}]收到报文→{BitConverter.ToString(data).ToLower()}");

            var payload = new RecvMsgEventPayLoad
            {
                key = key,
                data = data
            };
            _evtAggr.GetEvent<RecvMsgEvent>().Publish(payload);
        }
        #endregion

        #endregion
    }
}
